{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "12a0c405",
   "metadata": {},
   "source": [
    "---\n",
    "* 记录人：邱星倩\n",
    "* 时间：2021-11-29\n",
    "* week14\n",
    "* 主要参考文档：\n",
    "> 1.[python官方文档](https://www.python.org/doc/)  \n",
    "> 2.[许老师博客](https://www.cnblogs.com/xuzhichao/p/11570285.html)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8fdd0e26",
   "metadata": {},
   "source": [
    "# ★ 本周学习目标\n",
    "\n",
    "> 1.函数的定义  \n",
    "> 2.函数的使用  \n",
    "> 3.函数的参数  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "439ffd08",
   "metadata": {},
   "source": [
    "# （一）函数的定义"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4259bc5a",
   "metadata": {},
   "source": [
    "* 定义一个函数的一般步骤"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "3478aa17",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 \n",
      "1 \n",
      "1 \n",
      "2 \n",
      "3 \n",
      "5 \n",
      "8 \n"
     ]
    }
   ],
   "source": [
    "a, b = 0, 1\n",
    "while a < 10:                      \n",
    "    print(a, end=' ')\n",
    "    a, b = b, a+b\n",
    "    print()             # print()  ---> 换行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "c46e66af",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 \n",
      "1 \n",
      "1 \n",
      "2 \n",
      "3 \n",
      "5 \n",
      "8 \n",
      "13 \n"
     ]
    }
   ],
   "source": [
    "a, b = 0, 1\n",
    "while a < 20:                    # 较为麻烦，查询一次要重新写一次代码\n",
    "    print(a, end=' ') \n",
    "    a, b = b, a+b\n",
    "    print()  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "53323564",
   "metadata": {},
   "outputs": [],
   "source": [
    "# .....如果想重复使用某一个功能（避免重复造轮子）\n",
    "#......使用的人可以不懂代码，只要会调用函数即可 function_name()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4419ef0f",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fbdf84b0",
   "metadata": {},
   "source": [
    "## 1.定义函数的一般方法："
   ]
  },
  {
   "cell_type": "raw",
   "id": "08367c0c",
   "metadata": {},
   "source": [
    "...  \n",
    "def function_name():      # 1.function_name 遵循变量定义的规则  区别数学函数--->f(x)   python 的函数可以自定义名称  \n",
    "\"\"\"函数的注释\"\"\"         # 2.函数的注释可以和使用者交流   \n",
    "    函数体            # 3.函数体要和定义函数保持一定的tab缩进  \n",
    "...  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "3cd74520",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "def info(n):                   # def:定义函数的关键字  定义函数名info  参数为n\n",
    "    a, b = 0, 1\n",
    "    while a < n:                    # 函数体\n",
    "        print(a, end=' ')\n",
    "        a, b = b, a+b\n",
    "print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "60b7ba8f",
   "metadata": {},
   "source": [
    "# （二）函数的使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c4c7f286",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 "
     ]
    }
   ],
   "source": [
    "info(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "ed2ddb5c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 "
     ]
    }
   ],
   "source": [
    "info(50)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "e371beb1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 55 89 "
     ]
    }
   ],
   "source": [
    "info(100)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bf334c12",
   "metadata": {},
   "source": [
    "&emsp;"
   ]
  },
  {
   "cell_type": "raw",
   "id": "4e6e270d",
   "metadata": {},
   "source": [
    "## 练习\n",
    "写一个函数 实现 hello world\n",
    "写一个函数 实现 hello username"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "bdbb0145",
   "metadata": {},
   "outputs": [],
   "source": [
    "def hello():                  # 定义函数名为hello \n",
    "    \"\"\"打印 hello world\"\"\"       # 注释\n",
    "    print('hello world')      # 代码块"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "bb7d2b6e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n"
     ]
    }
   ],
   "source": [
    "hello()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "9c2385c7",
   "metadata": {},
   "outputs": [],
   "source": [
    "def username(username):\n",
    "    \"\"\"打印 你好同学\"\"\"\n",
    "    print('hello,'+ username.title()+'同学~')   # title() 方法返回一个字符串，其中每个单词的第一个字符均为大写"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "196748c5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello,Xiaoqiu同学~\n"
     ]
    }
   ],
   "source": [
    "username('xiaoqiu')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "950e2a11",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "326050b3",
   "metadata": {},
   "source": [
    "* 思考：函数是否必须有 参数？\n",
    "* 注意：\n",
    ">（1）在第一行定义函数中，不需要任何信息就能完成工作，因此括号是空的（即便如此，括号必不可少！）  \n",
    ">（2）要调用函数，可以依次指定函数名以及括号括起的必要信息。因为此函数hello()括号中不需要任何信息，只需要输入hello（）即可。和预期效果一样，打印Hello！"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d17d70a1",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7fa3e266",
   "metadata": {},
   "source": [
    "# (三）函数的参数\n",
    "> 1.形式参数：\n",
    ">> a.定义函数时，写在括号里面的参数  \n",
    ">> b.定义函数时，形式参数不占用空间  \n",
    "\n",
    "> 2.实际参数：\n",
    ">> a.调用函数时，写在括号里面的参数  \n",
    ">> b.使用函数时，形式参数 被 分配空间，变为实际参数  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eae41cb1",
   "metadata": {},
   "source": [
    "&emsp;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "58ff0153",
   "metadata": {},
   "outputs": [],
   "source": [
    "def describe_pet(animal_type,pet_name):     # 关键字 + 函数名 + （）+ 形式参数\n",
    "    \"\"\"显示宠物信息\"\"\"           \n",
    "    print(\"\\nI have a \" + animal_type + \".\")         # 字符串 + 形式参数 + 字符串 （字符串拼接）\n",
    "    print(\"My \" + animal_type + \"'s name is \"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "d913a691",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "describe_pet('dog','豆豆')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96013600",
   "metadata": {},
   "source": [
    "&emsp;"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4403022d",
   "metadata": {},
   "source": [
    "* 当函数具有多个参数时\n",
    "\n",
    "> 1.位置参数  \n",
    ">> a.形式参数有先后顺序，函数调用过程中应考虑参数的先后顺序，避免出现顺序错误的笑话  \n",
    ">> b.调用函数过程中要考虑形式参数的个数 \n",
    "\n",
    "> 2.关键字参数  \n",
    ">> a.调用函数时，通过赋值的方式传递给定义好的形式参数变量数据  \n",
    ">> b.关键字参数不考虑先后顺序，因为是指定变量赋值  \n",
    "\n",
    "> 3.默认参数\n",
    ">> a.在形式参数中，提前预先设置一个用户可能使用的参数值  \n",
    ">> b.用户在使用/调用函数时，可以默认不给默认参数赋值  \n",
    ">> c .用户在使用参数赋值，将替换默认参数的值  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "759b1d5c",
   "metadata": {},
   "source": [
    "&emsp;"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7df5948",
   "metadata": {},
   "source": [
    "### (1) 位置参数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "de05ad0e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "# 在使用 describe_pet() 函数时 需要考虑 参数的位置，从而进行参数数据的输入（实参的调用）\n",
    "describe_pet(\"dog\",\"豆豆\") #　要根据　形式参数的位置先后顺序　先写animal_type，再写pet_name"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bb6c7357",
   "metadata": {},
   "source": [
    "&emsp;"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f87ae06e",
   "metadata": {},
   "source": [
    "### (2) 关键字参数:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "58ccf68d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(pet_name='豆豆',animal_type='dog')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a0642f83",
   "metadata": {},
   "source": [
    "&emsp;"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "446061fa",
   "metadata": {},
   "source": [
    "### (3)默认参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "e9c6b9c7",
   "metadata": {},
   "outputs": [],
   "source": [
    "def describe_pet(pet_name,animal_type=\"dog\"):       # 关键字参数放在末尾\n",
    "    \"\"\"\n",
    "    显示宠物信息\n",
    "    通过打印的方式显示宠物类型和宠物名称\n",
    "    参数信息：\n",
    "    pet_name： 是一个字符串，宠物名称\n",
    "    animal_type：是一个字符串，宠物类型\n",
    "    \"\"\"\n",
    "    print(\"\\nI have a \" + animal_type + \".\")\n",
    "    print(\"My\" + animal_type + \"'s name is \"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "b7bd94db",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "Mydog's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"豆豆\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "50fceeb2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a cat.\n",
      "Mycat's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"豆豆\",\"cat\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7086490c",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "26352a7d",
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "# help(time)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "fb7afd0d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function describe_pet in module __main__:\n",
      "\n",
      "describe_pet(pet_name, animal_type='dog')\n",
      "    显示宠物信息\n",
      "    通过打印的方式显示宠物类型和宠物名称\n",
      "    参数信息：\n",
      "    pet_name： 是一个字符串，宠物名称\n",
      "    animal_type：是一个字符串，宠物类型\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(describe_pet)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5fd604a8",
   "metadata": {},
   "source": [
    "&emsp;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "91fe6f4b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n",
      "hello\n"
     ]
    }
   ],
   "source": [
    "print(\"hello\",'\\n',\"hello\",sep='')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "bf0bc34d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function print in module builtins:\n",
      "\n",
      "print(...)\n",
      "    print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n",
      "    \n",
      "    Prints the values to a stream, or to sys.stdout by default.\n",
      "    Optional keyword arguments:\n",
      "    file:  a file-like object (stream); defaults to the current sys.stdout.\n",
      "    sep:   string inserted between values, default a space.\n",
      "    end:   string appended after the last value, default a newline.\n",
      "    flush: whether to forcibly flush the stream.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(print)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a6365ec",
   "metadata": {},
   "source": [
    "---\n",
    "* 参数使用过程中的思考与问题：\n",
    "\n",
    "> 1.关键字参数 和 位置参数 是否可以一起使用  \n",
    "> 2.定义函数： 默认参数和非默认参数的关系\n",
    "----\n",
    "* 以下为测试代码：\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "de4d400e",
   "metadata": {},
   "outputs": [],
   "source": [
    "def test1(x,y,z):\n",
    "    \"\"\"打印x,y,z的值\"\"\"\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "c38b4cf4",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "positional argument follows keyword argument (<ipython-input-23-fd583303ea9b>, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-23-fd583303ea9b>\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m    test1(x=2,3,z=4)\u001b[0m\n\u001b[1;37m              ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m positional argument follows keyword argument\n"
     ]
    }
   ],
   "source": [
    "test1(x=2,3,z=4)     # 关键字参数应该跟在数字参数后面"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "7a7bacb9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "3\n",
      "4\n"
     ]
    }
   ],
   "source": [
    "test1(2,y=3,z=4)     # x=2 y=3 z=4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "86c001d0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "3\n",
      "4\n"
     ]
    }
   ],
   "source": [
    "test1(2,z=4,y=3)    # x=2 y=3 z=4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "e43f27c8",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "test1() got multiple values for argument 'x'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-25-abf767fdec53>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mtest1\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: test1() got multiple values for argument 'x'"
     ]
    }
   ],
   "source": [
    "test1(2,x=3,y=1)    # 多个值赋给了x !!!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "9ba88b6b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 案例2：\n",
    "def test1(x,z,y=3):\n",
    "    \"\"\"打印x,y,z的值\"\"\"\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "664274a0",
   "metadata": {},
   "source": [
    "&emsp;"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51f44c4f",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bee2c5e3",
   "metadata": {},
   "source": [
    "# (四）课本练习实践\n",
    "> 1.请大家总结函数的优势  \n",
    "> 2.预习课本第四章函数与模块  \n",
    "> 3.完成课本元音字母实践  \n",
    "> 4.浏览模块，创建模块和调用模块，了解PEP 8 python国际代码标准  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42c7cfa7",
   "metadata": {},
   "source": [
    "&emsp;"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20e52e32",
   "metadata": {},
   "source": [
    "### 1.函数的优势"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8d73b013",
   "metadata": {},
   "source": [
    "* 特点：\n",
    "> 1.代表执行单独的操作。    \n",
    "> 2.采用另个或多个参数作为输入。   \n",
    "> 3.返回值（可能是复合对象）作为输出。   "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "78c581bc",
   "metadata": {},
   "source": [
    "* 优点：\n",
    "> （1）减少重复代码   \n",
    "> （2）模块化代码   \n",
    "> （3）函数很重要，因为它代表一种封装。通过封装可以隐藏操作细节，函数可以表示操作的性能，而读者不需要了解操作的具体运行细节。  \n",
    "> （4）只需嵌入少量可执行代码，就能使代码结构更加简洁，从而大大简化代码复杂性，提高代码可读性。  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22d54bb8",
   "metadata": {},
   "source": [
    "&emsp;"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8db81e1b",
   "metadata": {},
   "source": [
    "### 2. 完成课本元音字母实践"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "4fcea820",
   "metadata": {},
   "outputs": [],
   "source": [
    "def searchvowels(word):\n",
    "    \"\"\"判断文本出现的元音字母有哪些\"\"\"\n",
    "    vowels = set('aeiou')\n",
    "    word = set(word)\n",
    "    print(vowels & word)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "847aa2f3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'e', 'i', 'u'}\n"
     ]
    }
   ],
   "source": [
    "searchvowels('euwruenwejdpqwiruy')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "49af3fec",
   "metadata": {},
   "source": [
    "&emsp;"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61852ca8",
   "metadata": {},
   "source": [
    "### 3.了解PEP 8 python国际代码标准"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6eed8b9d",
   "metadata": {},
   "source": [
    "#### (1) Code lay-out 代码布局"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a6731898",
   "metadata": {},
   "source": [
    "#### ▲ 缩进"
   ]
  },
  {
   "cell_type": "raw",
   "id": "f577e885",
   "metadata": {},
   "source": [
    "每一级缩进使用4个空格。\n",
    "续行应该与其包裹元素对齐，要么使用圆括号、方括号和花括号内的隐式行连接来垂直对齐，要么使用挂行缩进对齐。\n",
    "当使用挂行缩进时，应该考虑到第一行不应该有参数，以及使用缩进以区分自己是续行。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "927c65a9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 与左括号对齐\n",
    "foo = long_function_name(var_one, var_two,\n",
    "                         var_three, var_four)\n",
    "\n",
    "# 用更多的缩进来与其他行区分\n",
    "def long_function_name(\n",
    "        var_one, var_two, var_three,\n",
    "        var_four):\n",
    "    print(var_one)\n",
    "\n",
    "# 挂行缩进应该再换一行\n",
    "foo = long_function_name(\n",
    "    var_one, var_two,\n",
    "    var_three, var_four)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c06a548d",
   "metadata": {},
   "source": [
    "&emsp;"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f4e9fb66",
   "metadata": {},
   "source": [
    "#### （2）表达式和语句中的空格"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f4730161",
   "metadata": {},
   "outputs": [],
   "source": [
    "*在下列情况下，避免使用无关的空格："
   ]
  },
  {
   "cell_type": "raw",
   "id": "816b4e42",
   "metadata": {},
   "source": [
    "紧跟在小括号，中括号或者大括号后。\n",
    "Yes: spam(ham[1], {eggs: 2})\n",
    "No:  spam( ham[ 1 ], { eggs: 2 } )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "452a1a7d",
   "metadata": {},
   "source": [
    "&emsp;"
   ]
  },
  {
   "cell_type": "raw",
   "id": "598c51a1",
   "metadata": {},
   "source": [
    "紧贴在逗号、分号或者冒号之前。\n",
    "Yes: if x == 4: print x, y; x, y = y, x\n",
    "No: if x == 4 : print x , y ; x , y = y , x"
   ]
  },
  {
   "cell_type": "raw",
   "id": "e2980b67",
   "metadata": {},
   "source": [
    "冒号在切片中就像二元运算符，在两边应该有相同数量的空格\n",
    "\n",
    "推荐：\n",
    "\n",
    "ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]\n",
    "ham[lower:upper], ham[lower:upper:], ham[lower::step]\n",
    "ham[lower+offset : upper+offset]\n",
    "ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]\n",
    "ham[lower + offset : upper + offset]\n",
    "不推荐：\n",
    "\n",
    "ham[lower + offset:upper + offset]\n",
    "ham[1: 9], ham[1 :9], ham[1:9 :3]\n",
    "ham[lower : : upper]\n",
    "ham[ : upper]"
   ]
  },
  {
   "cell_type": "raw",
   "id": "6d9e697f",
   "metadata": {},
   "source": [
    "紧贴在函数参数的左括号之前。\n",
    "Yes: spam(1)\n",
    "No: spam (1)"
   ]
  },
  {
   "cell_type": "raw",
   "id": "f28dd23f",
   "metadata": {},
   "source": [
    "紧贴索引或者切片的左括号之前。\n",
    "Yes: dct['key'] = lst[index]\n",
    "No: dct ['key'] = lst [index]"
   ]
  },
  {
   "cell_type": "raw",
   "id": "e09739fe",
   "metadata": {},
   "source": [
    "为了和另一个赋值语句对齐，在赋值运算符附件加多个空格。 \n",
    "推荐：\n",
    "\n",
    "x = 1\n",
    "y = 2\n",
    "long_variable = 3"
   ]
  },
  {
   "cell_type": "raw",
   "id": "265d9a33",
   "metadata": {},
   "source": [
    "避免在尾部添加空格。因为尾部的空格通常都看不见，会产生混乱：比如，一个反斜杠后面跟一个空格的换行符，不算续行标记。"
   ]
  },
  {
   "cell_type": "raw",
   "id": "6c70f30d",
   "metadata": {},
   "source": [
    "总是在二元运算符两边加一个空格：赋值（=），增量赋值（+=，-=），比较（==,<,>,!=,<>,<=,>=,in,not,in,is,is not），布尔（and, or, not）。"
   ]
  },
  {
   "cell_type": "raw",
   "id": "3f32c7df",
   "metadata": {},
   "source": [
    "如果使用具有不同优先级的运算符，请考虑在具有最低优先级的运算符周围添加空格。"
   ]
  },
  {
   "cell_type": "raw",
   "id": "dd95c613",
   "metadata": {},
   "source": [
    "推荐：\n",
    "\n",
    "i = i + 1\n",
    "submitted += 1\n",
    "x = x*2 - 1\n",
    "hypot2 = x*x + y*y\n",
    "c = (a+b) * (a-b)\n",
    "不推荐：\n",
    "\n",
    "i=i+1\n",
    "submitted +=1\n",
    "x = x * 2 - 1\n",
    "hypot2 = x * x + y * y\n",
    "c = (a + b) * (a - b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "357dbbf2",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f4a32656",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "59c31965",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
